package org.proxywars.engine.rts;

import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;

public interface IUnit extends IAttributed {

	/**
	 * Tells the caller, if this unit is a mobile unit.
	 * 
	 * @return
	 */
	boolean isMobile();

	/**
	 * Returns the currently selected target of that unit. This may be a
	 * opponent unit to be attacked, or a freindly unit to be supported/repaired
	 * or what ever
	 * 
	 * @return The targeted unit
	 */
	IUnit getTarget();

	/**
	 * Selects a unit. All commands, that need a target, can only be executed,
	 * if a target is selected (for example attacking some oppnent)
	 * 
	 * @param target
	 */
	void setTarget(IUnit target);

	/**
	 * Each unit has an owner. This can be a human player, or a computer
	 * controlled enemy. This method sets the owner. Usually, the ownership of
	 * units is determined at creation time, so implementors may set the owner
	 * in one of their constructors. But its also possible to switch ownership
	 * at runtime (for example, if a building is beeing occupied by a party for
	 * a certain time)
	 * 
	 * @param owner
	 */
	void setOwner(IParty owner);

	/**
	 * This method returns the current owner of this unit.
	 * 
	 * @return
	 */
	IParty getOwner();

	/**
	 * Units can be part of larger groups. With this method, a unit may join a
	 * group. To join a group, the unit must meet some criteria. This criteria
	 * is defined by the group.
	 * 
	 * @param group
	 */
	void joinGroup(IUnitGroup group);

	/**
	 * With this method, the unit leaves a group
	 * 
	 * @param group
	 */
	void leaveGroup(IUnitGroup group);

	/**
	 * Commands are executed in reaction of events. At a given time, only one
	 * command is beeing executed.
	 * 
	 * @param command
	 */
	void addCommand(ICommand command);

	/**
	 * This is the command that is beeing process at this moment. Commands take
	 * time to finish.
	 * 
	 * @return
	 */
	ICommand getCurrentCommand();

	/**
	 * Returns the current command queue
	 * 
	 * @return
	 */
	Queue<ICommand> getCommands();

	/**
	 * With this method, the unit can be geared with some equipment.
	 * 
	 * @param equipment
	 */
	void addEquipment(IEquipment equipment);

	/**
	 * Returns the whole equipment if this unit. So the caller can determine the
	 * strength of the armor (for example)
	 * 
	 * @return
	 */
	List<IEquipment> getEquipment();

	/**
	 * This is the central processing method of a unit. Events can be external,
	 * like the information about beeing attacked, or timed.
	 * 
	 * @param event
	 */
	void handleEvent(IEvent event);
}
